package nbp.currency.logic;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import nbp.currency.shard.CurrencyExchangeDTO;
import nbp.currency.shard.CurrencyService;

public class CurrencyExchangeService {

	private static CurrencyExchangeService service;
	private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyMMdd");

	private PropertiesHelper properties;
	private DownloaderFile downloader;
	private NBPService nbpService;
	private XMLParser xmlParser;
	private CurrencyService currencyService;
	private HolidayService holidayService;

	private CurrencyExchangeService() {
		properties = new PropertiesHelper();
		downloader = new DownloaderFile();
		nbpService = new NBPService();
		xmlParser = new XMLParser();
		currencyService = new CurrencyService();
		holidayService = new HolidayService();

	}

	public static CurrencyExchangeService getInstance() {
		if (service == null) {
			service = new CurrencyExchangeService();
		}
		return service;
	}

	public CurrencyExchangeDTO getCurrencyExchange(CurrencyType currencyType, Date date) {

		Date workingDay = holidayService.getLastWorkingDateBefore(date);
		String fileName = DATE_FORMAT.format(workingDay) + properties.getEXTENSION();

		CurrencyExchangeDTO currency = currencyService.getCurrency(currencyType, workingDay);
		if (currency == null) {
			String xmlFile = nbpService.getXMLFileFromNBP(DATE_FORMAT.format(workingDay), properties.getURL_DIR_FILE(), properties.getEXTENSION());
			downloader.copyFileFromNBP(xmlFile, fileName, properties.getURL_NBP());
			CurrencyExchangeDTO parseXML = xmlParser.parseXML(fileName, currencyType);
			parseXML.setDate(workingDay);
			currencyService.addCurrency(parseXML);
			return parseXML;
		}

		return currency;
	}

	public List<CurrencyExchangeDTO> getCurrencyExchange(CurrencyType currencyType, Date dateFrom, Date dateTo) {

		List<CurrencyExchangeDTO> currencyExchangeDTOs = new ArrayList<CurrencyExchangeDTO>();

		Calendar calendar = GregorianCalendar.getInstance();
		calendar.setTime(dateFrom);

		while (calendar.getTime().compareTo(dateTo) <= 0) {
			CurrencyExchangeDTO currencyExchange = getCurrencyExchange(currencyType, calendar.getTime());
			currencyExchangeDTOs.add(currencyExchange);
			calendar.add(Calendar.DAY_OF_YEAR, 1);
		}
		return currencyExchangeDTOs;
	}

	public void updateCurrencyExchange(CurrencyExchangeDTO currencyExchangeDTO) {
		currencyService.updateCurrencyExchange(currencyExchangeDTO);
	}

	public void deleteCurrencyExchange(CurrencyExchangeDTO currencyExchangeDTO) {
		currencyService.deleteCurrencyExchange(currencyExchangeDTO);
	}

	public CurrencyType getBiggestDifferenceExchange(Date dateFrom, Date dateTo) {

		Date lastWorkingDateBeforeDateFrom = holidayService.getLastWorkingDateBefore(dateFrom);
		Date lastWorkingDateBefore = holidayService.getLastWorkingDateBefore(dateTo);

		CurrencyType currencyType = currencyService.getBiggestDifferenceExchange(lastWorkingDateBeforeDateFrom, lastWorkingDateBefore);
		return currencyType;
	}

	public Collection<CurrencyExchangeDTO> getTop5Exchange(CurrencyType currencyType) {
		Collection<CurrencyExchangeDTO> top5Exchange = currencyService.getTop5Exchange(currencyType);
		return top5Exchange;
	}

	public BigDecimal getMixExchange(Date dateFrom, Date dateTo, CurrencyType currencyType) {
		BigDecimal mixExchange = currencyService.getMinExchange(dateFrom, dateTo, currencyType);
		return mixExchange;
	}

	public BigDecimal getMaxExchange(Date dateFrom, Date dateTo, CurrencyType currencyType) {
		BigDecimal maxExchange = currencyService.getMaxExchange(dateFrom, dateTo, currencyType);
		return maxExchange;
	}

	public void deleteCurrencyExchange(CurrencyType currencyType, Date date) {
		currencyService.deleteCurrencyExchange(currencyType, date);
	}
}
